# @File    : JBL.py
# @Project : JBL_Android&iOS
import collections
from threading import Event, Thread
from PyQt5.QtCore import Qt, QFileSystemWatcher, QObject, pyqtSignal
from PyQt5.QtGui import QTextCharFormat
from airtest.core.api import *
from PyQt5 import uic
from PyQt5.QtWidgets import QMessageBox
from common.connect import ConnectUtil
from common.yamlUtil import YamlUtil
from page.android import AndroidUtil
from page.ios import IosUtil


class OtaUI:

    android_path = os.path.abspath(os.path.dirname
                                   (os.path.dirname(__file__))) + "\\" + "logs" + "\\" + "android.log"
    ios_path = os.path.abspath(os.path.dirname
                               (os.path.dirname(__file__))) + "\\" + "logs" + "\\" + "ios.log"
    process_path = os.path.abspath(os.path.dirname
                                   (os.path.dirname(__file__))) + "\\" + "data" + "\\" + "process.txt"
    event = Event()
    connect = ConnectUtil()
    da = YamlUtil("data.yaml")
    conf = YamlUtil("config.yaml")
    num = None

    def __init__(self):
        # 从文件中加载UI定义
        self.ui = uic.loadUi("View/JBL.ui")
        self.ui.start_log.clicked.connect(self.print_message)
        self.ui.stop_log.clicked.connect(self.stop_log)
        self.ui.clear_log.clicked.connect(self.clear_log)
        self.ui.connect_phone.clicked.connect(self.connect_phone)
        self.ui.disconnect_phone.clicked.connect(self.disconnect_phone)
        self.ui.ota_process.setVisible(False)
        self.ui.confirm.clicked.connect(self.check_input)

        # 读取日志路径
        self.log_android_path = self.android_path
        self.log_ios_path = self.ios_path
        self.android_last_modified_time = os.path.getmtime(self.log_android_path)
        self.ios_last_modified_time = os.path.getmtime(self.log_ios_path)
        self.process_last_modified_time = os.path.getmtime(self.process_path)
        # self.ui.tab_log.currentChanged.connect(self.tap_name)
        # self.file_modified = pyqtSignal()
        # self.file_watcher = QFileSystemWatcher()
        # self.file_watcher.addPath(self.process_path)
        # self.file_watcher.fileChanged(self.process)
        # self.file_modified.emit()


    # 开启日志打印
    def start_log(self):
        def start():
            self.ui.ota_process.setRange(0, 50)
            self.ui.ota_process.setValue(0)
            self.ui.ota_process.setVisible(True)
            for i in range(51):
                # info(f"现在是第 {i} 次")
                sleep(1)
            print("结束")
            sleep(5)
            self.ui.ota_process.setVisible(False)
            self.ui.ota_process.setValue(0)

        def process():
            for i in range(51):
                self.ui.ota_process.setValue(i)
                sleep(1)
            # currentTab = self.ui.tab_log.currentWidget().objectName()
            # while True:
            #     if currentTab == "Android":
            #         right("开启打印Android日志的线程")
            #         sleep(2)
            #         if self.event.is_set():
            #             right("关闭打印Android日志线程")
            #             break
            #     elif currentTab == "iOS":
            #         print("开启打印iOS日志的线程")
            #         if self.event.is_set():
            #             print("关闭打印iOS日志线程")
            #             break

        start_thread = Thread(target=start)
        process_thread = Thread(target=process)
        start_thread.start()
        process_thread.start()

    # 清理日志
    def clear_log(self):
        currentTab = self.ui.tab_log.currentWidget().objectName()
        if currentTab == "Android":
            # 清理Android日志
            self.ui.android_log.clear()
        elif currentTab == "iOS":
            # 清理iOS日志
            self.ui.iOS_log.clear()

    # 连接手机
    def connect_phone(self):
        ios = IosUtil()
        android = AndroidUtil()

        if self.ui.phone.currentText() == "Android":
            # 连接Android手机
            self.connect.connect_android()
            # 循环升级
            self.ui.android_cycle.clicked.connect(lambda: android.cycle_upgrade(self.num))
            # 升降级
            self.ui.android_updown.clicked.connect(lambda: android.promotion_demotion(self.num))
            # self.ui.android_updown.clicked.connect(android.read_process)
            self.ui.android_updown.clicked.connect(self.process)
            # 取消升级
            self.ui.android_cancel.clicked.connect(lambda: android.cancel_ota(self.num))
            # 中断升级
            self.ui.android_kill.clicked.connect(lambda: android.kill_ota(self.num))
        elif self.ui.phone.currentText() == "iOS":
            # 连接iOS手机
            ios.connect_ios()
            # 循环升级
            self.ui.ios_cycle.clicked.connect(lambda: ios.cycle_upgrade(self.num))
            # 升降级
            self.ui.ios_updown.clicked.connect(lambda: ios.promotion_demotion(self.num))
            self.ui.ios_updown.clicked.connect(ios.read_process)
            self.ui.ios_updown.clicked.connect(self.process)
            # 取消升级
            self.ui.ios_cancel.clicked.connect(lambda: ios.cancel_ota(self.num))
            # 中断升级
            self.ui.ios_kill.clicked.connect(lambda: ios.kill_ota(self.num))

    # 手机断连(暂时无效果)
    def disconnect_phone(self):
        if self.ui.phone.currentText() == "Android":
            self.connect.disconnect_android()
            stop_app("jbl.stc.com.debug")

    # ota进度条(目前只能显示第一次，需要继续完善一下)
    def process(self):
        def p():
            while True:
                current_modified_time = os.path.getmtime(self.process_path)
                if current_modified_time != self.process_last_modified_time:
                    self.ui.ota_process.setRange(0, 100)

                    self.ui.ota_process.setVisible(True)
                    last_line = self.tail(self.process_path, line=1)
                    if last_line:
                        for line in last_line:
                            self.ui.ota_process.setValue(int(line))
                            if self.ui.ota_process.value() == 100:
                                sleep(5)
                                self.ui.ota_process.setVisible(False)
                                self.ui.ota_process.setValue(0)
                                break
                        self.process_last_modified_time = current_modified_time

        p_thread = Thread(target=p)
        p_thread.start()

    # 版本号和压测次数处理方法
    def check_input(self):
        def check():
            data = {}
            if self.ui.version_2.text() == "" or self.ui.version_1.text() == "":
                QMessageBox.warning(
                    self.ui,
                    '错误',
                    '请输入需要压测的版本号!!!')
            elif self.ui.test_time.text() == "":
                QMessageBox.warning(
                    self.ui,
                    '错误',
                    '请输入需要压测的次数!!!')
            if self.ui.version_1.text() != self.ui.version_2.text():
                if self.ui.version_1.text() > self.ui.version_2.text():
                    h_version = self.ui.version_1.text()
                    l_version = self.ui.version_2.text()
                else:
                    h_version = self.ui.version_2.text()
                    l_version = self.ui.version_1.text()
                data.update({'h_version': f'v{h_version}',
                             'l_version': f'v{l_version}',
                             's_h_version': h_version,
                             's_l_version': l_version,
                             'advanced_version_package': f'V{h_version}',
                             'low_version_package': f'V{l_version}',
                             'ota_times': self.ui.test_time.text(),
                             'device': self.ui.device.currentText()})
            elif self.ui.version_1.text() == self.ui.version_2.text():
                data.update({'c_version': f'v{self.ui.version_1.text()}',
                             's_c_version': self.ui.version_1.text(),
                             'cycle_version_package': f'V{self.ui.version_1.text()}',
                             'ota_times': self.ui.test_time.text(),
                             'device': self.ui.device.currentText()})
            self.da.clean_yaml()
            re = self.conf.yaml_template(data)
            self.da.write_yaml(re)
            self.num = self.ui.test_time.text()
        check_thread = Thread(target=check)
        check_thread.start()

    # 日志打印
    def print_message(self):
        def start():
            currentTab = self.ui.tab_log.currentWidget().objectName()
            while True:
                if currentTab == "Android":
                    current_modified_time = os.path.getmtime(self.log_android_path)
                    if self.event.is_set():
                        # 关闭打印Android日志线程
                        break
                    if current_modified_time != self.android_last_modified_time:
                        last_line = self.tail(self.log_android_path, line=1)
                        if last_line:
                            for line in last_line:
                                log_content = line
                                log_level = self.extract_log_level(log_content)
                                self.create_char_format(log_level, log_content, currentTab)
                            self.android_last_modified_time = current_modified_time
                elif currentTab == "iOS":
                    current_modified_time = os.path.getmtime(self.log_ios_path)
                    if self.event.is_set():
                        # 关闭打印Android日志线程
                        break
                    if current_modified_time != self.ios_last_modified_time:
                        last_line = self.tail(self.log_ios_path, line=1)
                        if last_line:
                            for line in last_line:
                                log_content = line
                                log_level = self.extract_log_level(log_content)
                                self.create_char_format(log_level, log_content, currentTab)
                            self.ios_last_modified_time = current_modified_time
                time.sleep(1)  # 每秒更新一次

        start_thread = Thread(target=start)
        self.event.clear()
        start_thread.start()
        self.ui.start_log.setEnabled(False)

    # 关闭日志打印
    def stop_log(self):
        self.event.set()
        self.ui.start_log.setEnabled(True)

    def extract_log_level(self, log_content):
        # 从日志内容中提取日志级别
        if "[DEBUG]" in log_content:
            return "DEBUG"
        elif "[INFO]" in log_content:
            return "INFO"
        elif "[WARNING]" in log_content:
            return "WARNING"
        elif "[ERROR]" in log_content:
            return "ERROR"
        elif "[CRITICAL]" in log_content:
            return "CRITICAL"
        else:
            return "UNKNOWN"

    def create_char_format(self, log_level, log_content, currentTab):
        char_format = QTextCharFormat()
        # 根据日志级别设置颜色
        if log_level == "DEBUG":
            char_format.setForeground(Qt.blue)
        elif log_level == "INFO":
            char_format.setForeground(Qt.darkGreen)
        elif log_level == "WARNING":
            char_format.setForeground(Qt.red)
        elif log_level == "ERROR" or log_level == "CRITICAL":
            char_format.setForeground(Qt.yellow)
        if currentTab == "Android":
            self.ui.android_log.setCurrentCharFormat(char_format)
            self.ui.android_log.insertPlainText(f"{log_content}\n")
            self.ui.android_log.ensureCursorVisible()
        elif currentTab == "iOS":
            self.ui.iOS_log.setCurrentCharFormat(char_format)
            self.ui.iOS_log.insertPlainText(f"{log_content}\n")
            self.ui.iOS_log.ensureCursorVisible()

    # 存储最新添加的日志
    def tail(self, file_path, line=1):
        last_line = collections.deque(maxlen=line)
        with open(file_path, "r", encoding="utf-8") as file:
            for line in file:
                last_line.append(line.strip())
        return last_line


